package com.ef.service.impl;

import java.util.Date;
import java.util.List;

import com.ef.constant.EClassEntityType;
import com.ef.constant.EClassLevel;
import com.ef.constant.EClassType;
import com.ef.constant.ELeadsClassStatus;
import com.ef.constant.EUserTodoObject;
import com.ef.constant.EUserTodoStatus;
import com.ef.constant.EUserTodoType;
import com.ef.constant.SystemContant;
import com.ef.dao.ClassArrangeDao;
import com.ef.dao.ClassBookingDao;
import com.ef.dao.LeadsClassEntityDao;
import com.ef.dao.LeadsDao;
import com.ef.dao.TodoEventDao;
import com.ef.domain.ClassEntity;
import com.ef.domain.ClassFocus;
import com.ef.domain.ClassUnit;
import com.ef.domain.Leads;
import com.ef.domain.LeadsClassEntity;
import com.ef.domain.User;
import com.ef.domain.UserTodoEvent;
import com.ef.service.ClassBookingService;
import com.ef.util.CalendarUtil;
import com.ef.web.domain.CardInfo;

public class ClassBookingServiceImpl extends BaseServiceImpl implements
		ClassBookingService {

	private ClassBookingDao classBookingDao;

	private ClassArrangeDao classArrangeDao;

	private LeadsDao leadsDao;

	private LeadsClassEntityDao leadsClassEntityDao;

	private TodoEventDao todoEventDao;

	public String doBooking(Long entityId, Long leadsId, EClassEntityType type,
			User user, String order, String comments) {
		ClassEntity classEntity = classArrangeDao.findById(entityId);
		if (classEntity == null) {
			return "<type>error</type><info>unknow Class Entity</info>";
		}
		if (type.equals(EClassEntityType.NORMAL)) {
			if (classEntity.getType().equals(EClassEntityType.NORMAL)) {
				return doNormalBooking(classEntity, leadsId, user, order,
						comments);
			} else if (classEntity.getType().equals(EClassEntityType.PSA)) {
				return this.doPSABooking(classEntity, leadsId, user, order,
						comments);
			} else if (classEntity.getType().equals(EClassEntityType.VIP)) {
				return "<type>error</type><info>can't do  VIP booking </info>";
			} else if (classEntity.getType().equals(EClassEntityType.FREEF2F)) {
				return this.doFreeF2FBooking(classEntity, leadsId, user);
			}
		} else if (type.equals(EClassEntityType.PSA)) {
			return doPSABooking(classEntity, leadsId, user, order, comments);
		} else if (type.equals(EClassEntityType.VIP)) {
			return doVIPBooking(classEntity, leadsId, user);
		} else if (type.equals(EClassEntityType.FREEF2F)) {
			return doFreeF2FBooking(classEntity, leadsId, user);
		}
		return "<type>error</type><info>unknow doBooking </info>";
	}

	public String changeAbsenceToCancel(Long leadsClassEntityId, User user) {
		LeadsClassEntity leadsClass = leadsClassEntityDao
				.findById(leadsClassEntityId);
		// 订课的leads
		Leads leads = leadsClass.getLeads();
		// 要订的课
		ClassEntity classEntity = leadsClass.getClassEntity();
		String comments = "";
		if (classEntity.needJudgeNet() && leads.isNeedJudgeNetLevel()) {
			if (leads.getNetLevelUnit() == null) {
				leads.setNetLevelUnit(-1);
				leads.setNetLevel(-1);
			}
			if (leads.getNetLevel() == null) {
				leads.setNetLevel(-1);
			}
			Integer nu = leads.getNetLevelUnit();
			if (nu == 1) {
				leads.setNetLevelUnit(8);
				int nL = leads.getNetLevel();
				if (nL > 1) {
					leads.setNetLevel(nL - 1);
				}
			} else {
				leads.setNetLevelUnit(leads.getNetLevelUnit() - 1);
			}
			String com1 = leadsClass.getComments();
			if (com1 == null || com1.trim().length() == 0) {
				comments = "[A2C]L" + leads.getNetLevel() + "U"
						+ leads.getNetLevelUnit();
			} else {
				comments = com1 + " [A2C]L" + leads.getNetLevel() + "U"
						+ leads.getNetLevelUnit();
			}
			leads.setChangeNetLevelTime(new Date());
			leadsDao.saveOrUpdate(leads);
		}
		leadsClass.setComments(comments);
		leadsClass.setClassStatus(ELeadsClassStatus.CANCEL);
		leadsClass.setCancelTime(new Date());
		leadsClass.setCancelUser(user);
		leadsClassEntityDao.saveOrUpdate(leadsClass);
		// 记下信息
		if (!(classEntity.getClassType().getType().equals(EClassType.WK) || classEntity
				.getClassType().getType().equals(EClassType.LC))) {
			classEntity.changeBookingStudentStatus(leadsClass);
		}
		classArrangeDao.saveOrUpdate(classEntity);
		Date lastCTime = leads.getLastCancelTime();
		if (lastCTime != null) {
			int week = CalendarUtil
					.getWeekOfYearWithMondayIsFirstDay(lastCTime);
			int nowweek = CalendarUtil
					.getWeekOfYearWithMondayIsFirstDay(new Date());
			if (week != nowweek) {
				leads.setCancelTimesInWeek(0);
			}
		}
		// SAVE Leads
		leads.addCancelTimesInWeek();
		leads.setLastCancelTime(new Date());
		leadsDao.saveOrUpdate(leads);
		String info = leads.getName() + "  CANCEL "
				+ classEntity.getClassFocus().getName() + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		if (comments != null && comments.trim().length() > 0) {
			info = info + " Net Level " + comments;
		}
		return boxResponseString("", classEntity, info);
	}

	public String changeWaitingToBooking(Long leadsClassEntityId,
			EClassEntityType type, User user) {
		LeadsClassEntity leadsClass = leadsClassEntityDao
				.findById(leadsClassEntityId);
		ClassEntity classEntity = leadsClass.getClassEntity();
		String info = "booking";
		String color = SystemContant.BOOKING_SELECTED_COLOR;
		if (leadsClass.getClassEntity().isFull()) {
			info = " this class is Full!";
			color = SystemContant.BOOKING_WAIT_COLOR;
			return boxResponseString(color, classEntity, info);
		} else {
			leadsClass.setOldStateTime(leadsClass.getBookingTime());
			leadsClass.setOldStateUser(leadsClass.getBookingUser());
			leadsClass.setBookingTime(new Date());
			leadsClass.setBookingUser(user);
			leadsClass.setBookingFromWaiting(true);
			leadsClass.setClassStatus(ELeadsClassStatus.BOOKING);
			classEntity.onlyAddBookingCount();
		}
		Leads leads = leadsClass.getLeads();
		// 调整net level
		String comments = "";
		if (classEntity.needJudgeNet()
				&& leads.isNeedJudgeNetLevel()
				&& leadsClass.getClassStatus()
						.equals(ELeadsClassStatus.BOOKING)) {
			if (leads.getNetLevelUnit() == null) {
				leads.setNetLevelUnit(-1);
				leads.setNetLevel(-1);
			}
			if (leads.getNetLevel() == null) {
				leads.setNetLevel(-1);
			}
			Integer nu = leads.getNetLevelUnit();
			if (nu == 8) {
				leads.setNetLevelUnit(1);
				leads.setNetLevel(leads.getNetLevel() + 1);
			} else {
				leads.setNetLevelUnit(leads.getNetLevelUnit() + 1);
			}
			leads.setChangeNetLevelTime(new Date());
			comments = "[W2B]L" + leads.getNetLevel() + "U"
					+ leads.getNetLevelUnit();
			leadsDao.saveOrUpdate(leads);
		}
		leadsClass.setComments(comments);
		leadsClassEntityDao.saveOrUpdate(leadsClass);
		classArrangeDao.saveOrUpdate(classEntity);
		String fname = "";
		if (leadsClass.getClassEntity().getClassFocus() != null) {
			fname = leadsClass.getClassEntity().getClassFocus().getName();
		}
		info = leads.getName() + " booking " + fname + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		if (comments != null && comments.trim().length() > 0) {
			info = info + " Net Level " + comments;
		}
		return boxResponseString(color, classEntity, info);
	}

	protected String doNormalBooking(ClassEntity classEntity, Long leadsId,
			User user, String order, String comments1) {
		// 订课的leads
		Leads leads = leadsDao.findById(leadsId);
		LeadsClassEntity leadsClass = new LeadsClassEntity();
		leadsClass.setLeads(leads);
		leadsClass.setClassEntity(classEntity);
		String bOrw = "booking";
		String color = SystemContant.BOOKING_SELECTED_COLOR;
		leadsClass.setBookingTime(new Date());
		leadsClass.setBookingUser(user);
		String netComments = "";
		if (classEntity.isFull()) {
			leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
			bOrw = "booking for waiting";
			color = SystemContant.BOOKING_WAIT_COLOR;
			classEntity.addBookingCount(false);
		} else {
			if (classEntity.haveWaitingStudent()) {
				leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
				bOrw = "somebody waiting, booking for waiting";
				color = SystemContant.BOOKING_WAIT_COLOR;
				classEntity.addBookingCount(false);
			} else {
				leadsClass.setClassStatus(ELeadsClassStatus.BOOKING);
				// 设置课程级别
				if (classEntity.getBookingCount() == 0 && classEntity.isF2F()) {
					classEntity.setClassLevel(leads.getCurrentlevel());
				}
				classEntity.addBookingCount(true);
			}
		}
		if (order != null && order.trim().length() > 0) {
			leadsClass.setClassOrder(Integer.valueOf(order.trim()));
		}
		// 记下信息
		if (!(classEntity.getClassType().getType().equals(EClassType.WK) || classEntity
				.getClassType().getType().equals(EClassType.LC))) {
			classEntity.addBookingStudent(leadsClass);
		}
		// 调整net level
		if (classEntity.needJudgeNet()
				&& leads.isNeedJudgeNetLevel()
				&& leadsClass.getClassStatus()
						.equals(ELeadsClassStatus.BOOKING)) {
			if (leads.getNetLevelUnit() == null) {
				leads.setNetLevelUnit(-1);
				leads.setNetLevel(-1);
			}
			if (leads.getNetLevel() == null) {
				leads.setNetLevel(-1);
			}
			Integer nu = leads.getNetLevelUnit();
			if (nu == 8) {
				leads.setNetLevelUnit(1);
				leads.setNetLevel(leads.getNetLevel() + 1);
			} else {
				leads.setNetLevelUnit(leads.getNetLevelUnit() + 1);
			}
			netComments = "[B]L" + leads.getNetLevel() + "U"
					+ leads.getNetLevelUnit();
			leads.setChangeNetLevelTime(new Date());
			leadsDao.saveOrUpdate(leads);
		}
		leadsClass.setComments(netComments);
		leadsClassEntityDao.save(leadsClass);
		classArrangeDao.saveOrUpdate(classEntity);
		String fname = "";
		if (classEntity.getClassFocus() != null) {
			fname = classEntity.getClassFocus().getName();
		}
		String info = leads.getName() + "  " + bOrw + " " + fname + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		if (netComments != null && netComments.trim().length() > 0) {
			info = info + " Net Level" + netComments;
		}
		return boxResponseString(color, classEntity, info);
	}

	protected String doPSABooking(ClassEntity classEntity, Long leadsId,
			User user, String order, String comments) {
		// 订课的leads
		Leads leads = leadsDao.findById(leadsId);
		LeadsClassEntity leadsClass = new LeadsClassEntity();
		leadsClass.setLeads(leads);
		leadsClass.setClassEntity(classEntity);
		String bOrw = "PSA booking";
		String color = SystemContant.BOOKING_SELECTED_COLOR;
		leadsClass.setBookingTime(new Date());
		leadsClass.setBookingUser(user);
		if (classEntity.isFull()) {
			leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
			bOrw = "booking PSA for waiting";
			color = SystemContant.BOOKING_WAIT_COLOR;
			classEntity.addBookingCount(false);
		} else {
			if (classEntity.haveWaitingStudent()) {
				leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
				bOrw = "somebody waiting,booking PSA for waiting";
				color = SystemContant.BOOKING_WAIT_COLOR;
				classEntity.addBookingCount(false);
			} else {
				leadsClass.setClassStatus(ELeadsClassStatus.BOOKING);
				classEntity.addBookingCount(true);
			}
		}
		if (order != null && order.trim().length() > 0) {
			leadsClass.setClassOrder(Integer.valueOf(order.trim()));
		} else {
			// 缺省是1
			leadsClass.setClassOrder(1);
		}
		// 记下comments
		classEntity.addBookingStudent(leadsClass);

		leadsClass.setComments(comments);
		leadsClassEntityDao.save(leadsClass);
		classEntity.setType(EClassEntityType.PSA);
		classArrangeDao.saveOrUpdate(classEntity);
		String info = leads.getName() + "  " + bOrw + " "
				+ classEntity.getClassFocus().getName() + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		return boxResponseString(color, classEntity, info);
	}

	protected String doVIPBooking(ClassEntity classEntity, Long leadsId,
			User user) {
		// 订课的leads
		Leads leads = leadsDao.findById(leadsId);
		LeadsClassEntity leadsClass = new LeadsClassEntity();
		leadsClass.setLeads(leads);
		leadsClass.setClassEntity(classEntity);
		String bOrw = "VIP booking  ";
		String color = SystemContant.BOOKING_SELECTED_COLOR;
		leadsClass.setBookingTime(new Date());
		leadsClass.setBookingUser(user);
		if (classEntity.isFull()) {
			leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
			bOrw = "booking VIP for waiting";
			color = SystemContant.BOOKING_WAIT_COLOR;
			classEntity.addBookingCount(false);
		} else {
			leadsClass.setClassStatus(ELeadsClassStatus.BOOKING);
			classEntity.addBookingCount(true);
		}
		// 记下comments
		classEntity.addBookingStudent(leadsClass);
		leadsClassEntityDao.save(leadsClass);
		classEntity.setType(EClassEntityType.VIP);
		classArrangeDao.saveOrUpdate(classEntity);
		String info = leads.getName() + "  " + bOrw + " "
				+ classEntity.getClassFocus().getName() + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		return boxResponseString(color, classEntity, info);
	};

	protected String doFreeF2FBooking(ClassEntity classEntity, Long leadsId,
			User user) {
		// 订课的leads
		Leads leads = leadsDao.findById(leadsId);
		LeadsClassEntity leadsClass = new LeadsClassEntity();
		leadsClass.setLeads(leads);
		leadsClass.setClassEntity(classEntity);
		String bOrw = "FreeF2F booking  ";
		String color = SystemContant.BOOKING_SELECTED_COLOR;
		leadsClass.setBookingTime(new Date());
		leadsClass.setBookingUser(user);
		if (classEntity.isFull()) {
			leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
			bOrw = "booking FreeF2F for waiting";
			color = SystemContant.BOOKING_WAIT_COLOR;
			classEntity.addBookingCount(false);
		} else {
			if (classEntity.haveWaitingStudent()) {
				leadsClass.setClassStatus(ELeadsClassStatus.WAITING);
				bOrw = "somebody waiting, booking for waiting";
				color = SystemContant.BOOKING_WAIT_COLOR;
				classEntity.addBookingCount(false);
			} else {
				leadsClass.setClassStatus(ELeadsClassStatus.BOOKING);
				classEntity.addBookingCount(true);
			}
		}
		// 记下comments
		classEntity.addBookingStudent(leadsClass);
		classEntity.setType(EClassEntityType.FREEF2F);
		classArrangeDao.saveOrUpdate(classEntity);
		String comments = "";
		// 调整net level
		if (classEntity.needJudgeNet()
				&& leads.isNeedJudgeNetLevel()
				&& leadsClass.getClassStatus()
						.equals(ELeadsClassStatus.BOOKING)) {
			if (leads.getNetLevelUnit() == null) {
				leads.setNetLevelUnit(-1);
				leads.setNetLevel(-1);
			}
			if (leads.getNetLevel() == null) {
				leads.setNetLevel(-1);
			}
			Integer nu = leads.getNetLevelUnit();
			if (nu == 8) {
				leads.setNetLevelUnit(1);
				leads.setNetLevel(leads.getNetLevel() + 1);
			} else {
				leads.setNetLevelUnit(leads.getNetLevelUnit() + 1);
			}
			comments = "[B]L" + leads.getNetLevel() + "U"
					+ leads.getNetLevelUnit();
			leads.setChangeNetLevelTime(new Date());
			leadsDao.saveOrUpdate(leads);
		}
		leadsClass.setComments(comments);
		leadsClassEntityDao.save(leadsClass);
		String info = leads.getName() + "  " + bOrw + " "
				+ classEntity.getClassFocus().getName() + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		if (comments != null && comments.trim().length() > 0) {
			info = info + " Net Level" + comments;
		}
		return boxResponseString(color, classEntity, info);
	}

	/*
	 * 完成课程取消,新增一条任务,需要重新BOOKING。
	 * 
	 * @see com.ef.service.ClassBookingService#doCancel(java.lang.Long,
	 * java.lang.Long)
	 */
	public String doCancel(Long entityId, Long leadsId, User user) {
		// 订课的leads
		Leads leads = leadsDao.findById(leadsId);
		// 要订的课
		ClassEntity classEntity = classArrangeDao.findById(entityId);
		LeadsClassEntity lclass = leadsClassEntityDao
				.getLeadsClassEntityWithClassEntity(entityId, leadsId);
		String color = SystemContant.BOOKING_PUNISH_COLOR;
		// 从WAIT直接CANCEL
		if (lclass.getClassStatus().equals(ELeadsClassStatus.WAITING)) {
			lclass.setClassStatus(ELeadsClassStatus.CLEAR);
			color = SystemContant.BOOKING_PUNISH_COLOR;
			lclass.setCancelTime(new Date());
			lclass.setCancelUser(user);
			leadsClassEntityDao.saveOrUpdate(lclass);
			// SAVE class
			classEntity.onlyMinusAllCount();
			// 记下commonts信息
			if (!(classEntity.getClassType().getType().equals(EClassType.WK) || classEntity
					.getClassType().getType().equals(EClassType.LC))) {
				classEntity.changeWaitStudentStatus(lclass);
			}
			classArrangeDao.saveOrUpdate(classEntity);
			String info = leads.getName() + "  CLEAR "
					+ classEntity.getClassFocus().getName() + " at "
					+ classEntity.getClassDate() + " "
					+ classEntity.getClassTime();
			return boxResponseString(color, classEntity, info);
		}
		// ///////////////BOOKING
		// CANCEL//////////////////////////////////////////////////////////
		EClassType cType = classEntity.getClassType().getType();
		Date date = classEntity.getClassDate();
		Date stime = classEntity.getClassTime().getStartTime();
		Date cdate = CalendarUtil.getDateTime(date, stime);
		Date now = new Date();
		int cday = CalendarUtil.getDayOfYear(cdate, CalendarUtil.getYear());
		int nday = CalendarUtil.getDayOfYear(now, CalendarUtil.getYear());
		long st = CalendarUtil.getDateTime(date, stime).getTime();
		long nowtime = new Date().getTime();
		String comments = "";
		// WK和LC的课 1小时定为 缺席
		if (cType.equals(EClassType.WK) || cType.equals(EClassType.LC)) {// WK和LC课
			if ((st - nowtime) > 3600000l) {
				lclass.setClassStatus(ELeadsClassStatus.CANCEL);
				color = SystemContant.BOOKING_PUNISH_COLOR;
			} else {
				lclass.setClassStatus(ELeadsClassStatus.ABSENCE);
				color = SystemContant.BOOKING_ABSENCE_COLOR;
			}
		} else if (cType.equals(EClassType.F2F)) {// F2F课
			// F2F 一天判断缺席
			if (nday < cday) {
				// F2F 取消
				lclass.setClassStatus(ELeadsClassStatus.CANCEL);
				color = SystemContant.BOOKING_PUNISH_COLOR;
				// 调整回 网络课程
				if (classEntity.needJudgeNet() && leads.isNeedJudgeNetLevel()) {
					if (leads.getNetLevelUnit() == null) {
						leads.setNetLevelUnit(-1);
						leads.setNetLevel(-1);
					}
					if (leads.getNetLevel() == null) {
						leads.setNetLevel(-1);
					}
					Integer nu = leads.getNetLevelUnit();
					if (nu == 1) {
						leads.setNetLevelUnit(8);
						int nL = leads.getNetLevel();
						if (nL > 1) {
							leads.setNetLevel(nL - 1);
						}
					} else {
						leads.setNetLevelUnit(leads.getNetLevelUnit() - 1);
					}
					String com1 = lclass.getComments();
					if (com1 == null || com1.trim().length() == 0) {
						comments = "[C]L" + leads.getNetLevel() + "U"
								+ leads.getNetLevelUnit();
					} else {
						comments = com1 + " [C]L" + leads.getNetLevel() + "U"
								+ leads.getNetLevelUnit();
					}
					leads.setChangeNetLevelTime(new Date());
					leadsDao.saveOrUpdate(leads);
				}
			} else {// F2F 缺席
				lclass.setClassStatus(ELeadsClassStatus.ABSENCE);
				color = SystemContant.BOOKING_ABSENCE_COLOR;
			}
		} else {// 其他课
			lclass.setClassStatus(ELeadsClassStatus.CANCEL);
			color = SystemContant.BOOKING_PUNISH_COLOR;
		}
		lclass.setComments(comments);
		lclass.setCancelTime(new Date());
		lclass.setCancelUser(user);
		leadsClassEntityDao.saveOrUpdate(lclass);
		// SAVE class
		classEntity.minusBookingCount();
		// 记下commonts信息
		if (!(classEntity.getClassType().getType().equals(EClassType.WK) || classEntity
				.getClassType().getType().equals(EClassType.LC))) {
			classEntity.changeBookingStudentStatus(lclass);
		}
		classArrangeDao.saveOrUpdate(classEntity);
		Date lastCTime = leads.getLastCancelTime();
		if (lastCTime != null) {
			int week = CalendarUtil
					.getWeekOfYearWithMondayIsFirstDay(lastCTime);
			int nowweek = CalendarUtil
					.getWeekOfYearWithMondayIsFirstDay(new Date());
			if (week != nowweek) {
				leads.setCancelTimesInWeek(0);
			}
		}
		// SAVE Leads
		leads.addCancelTimesInWeek();
		leads.setLastCancelTime(new Date());
		leadsDao.saveOrUpdate(leads);
//		// 新建任务
//		if (classEntity.haveWaitingStudent()) {// cancel后需提醒
//			String title = "";
//			UserTodoEvent todoEvent = new UserTodoEvent();
//			todoEvent.setCreateTime(new Date());
//			todoEvent.setTodoType(EUserTodoType.Call);
//			todoEvent
//					.setGoAction("/academic/ClassBooking/list?selClassEntityId="
//							+ entityId);
//			title = "NOTE: need to booking the waiting student ";
//			todoEvent.setCreateUser(user);
//			todoEvent.setReminderStartTime(new Date());
//			todoEvent.setReminderEndTime(CalendarUtil.getEndOfDay(CalendarUtil
//					.getEndOfDay(new Date())));
//			todoEvent.setToObject(EUserTodoObject.MySelf);
//			todoEvent.setToUser(user);
//			todoEvent.setStatus(EUserTodoStatus.Valid);
//			String todoEventComments = leads.getName() + " cancel the Class "
//					+ classEntity.getMessage() + ";Need ReBooking !";
//			todoEvent.setDetail(todoEventComments);
//			todoEvent.setTitle(title);
//			todoEventDao.saveOrUpdate(todoEvent);
//		}
		String info = leads.getName() + "  CANCEL "
				+ classEntity.getClassFocus().getName() + " at "
				+ classEntity.getClassDate() + " " + classEntity.getClassTime();
		if (comments != null && comments.trim().length() > 0) {
			info = info + " Net Level" + comments;
		}
		return boxResponseString(color, classEntity, info);
	}

	public void doCheckin(ClassEntity classEntiy, String leadsClassEntityIds,
			User user) {
		List<LeadsClassEntity> lClassEntitys = leadsClassEntityDao
				.getLeadsClassEntityListWithClassEntity(classEntiy);
		for (LeadsClassEntity lClassEntity : lClassEntitys) {
			if (lClassEntity.isCancel() || lClassEntity.isClear()) {// 已取消的不处理
				continue;
			}
			String id = lClassEntity.getId().toString();
			// 只对Booking的操作,不为booking的要求先做booking
			if (lClassEntity.isBooking() || lClassEntity.isCheckin()
					|| lClassEntity.isAbsence()) {
				if ((leadsClassEntityIds.indexOf(",") == -1 && leadsClassEntityIds
						.equals(id))
						|| ((leadsClassEntityIds.indexOf(id + ",") > -1 || leadsClassEntityIds
								.indexOf("," + id) > -1))) {
					if (lClassEntity.getClassEntity().getClassType().getType()
							.equals(EClassType.INTERVIEW)) {
						if (!lClassEntity.isCheckin()) {
							// 新建一个任务,要求调整level
							String title = "";
							UserTodoEvent todoEvent = new UserTodoEvent();
							todoEvent.setCreateTime(new Date());
							todoEvent.setTodoType(EUserTodoType.Call);
							todoEvent
									.setGoAction("/customer/PersonalTouch/edit?id="
											+ lClassEntity.getLeads().getId());
							title = "NOTE: need to modify the student level ";
							todoEvent.setCreateUser(user);
							todoEvent.setReminderStartTime(new Date());
							todoEvent.setReminderEndTime(CalendarUtil
									.getEndOfDay(CalendarUtil
											.getEndOfDay(new Date())));
							todoEvent.setToObject(EUserTodoObject.MySelf);
							todoEvent.setToUser(user);
							todoEvent.setStatus(EUserTodoStatus.Valid);
							String todoEventComments = lClassEntity.getLeads()
									.getName()
									+ " need modify there level";
							todoEvent.setDetail(todoEventComments);
							todoEvent.setTitle(title);
							todoEventDao.saveOrUpdate(todoEvent);
							// 完成OriginalInterview
							Leads leads = lClassEntity.getLeads();
							if (leads.getFinishedOriginalInterview() == null
									|| leads.getFinishedOriginalInterview() == false) {
								leads.setFinishedOriginalInterview(true);
								leadsDao.saveOrUpdate(leads);
							}
						}// end if chickin
					} else if (lClassEntity.getClassEntity().getClassType()
							.getType().equals(EClassType.OC)) {// 完成OC课程
						Leads leads = lClassEntity.getLeads();
						leads.setOriginalClassTime(new Date());
						leadsDao.saveOrUpdate(leads);
					}
					lClassEntity.setClassStatus(ELeadsClassStatus.CHECKIN);
				} else {// 未选到
					lClassEntity.setClassStatus(ELeadsClassStatus.ABSENCE);
				}
				// 完成FreeF2F 课程
				if (lClassEntity.getClassEntity().getType().equals(
						EClassEntityType.FREEF2F)) {
					Leads leads = lClassEntity.getLeads();
					if (leads.getFreeF2FCount() != null
							&& leads.getFreeF2FCount() > 0) {
						leads.setFreeF2FCount(leads.getFreeF2FCount() - 1);
					}
					leadsDao.saveOrUpdate(leads);
				}
			} else if (lClassEntity.isWaiting()) {
				lClassEntity.setClassStatus(ELeadsClassStatus.CLEAR);
			}
			lClassEntity.setCheckinTime(new Date());
			lClassEntity.setCheckinUser(user);
			leadsClassEntityDao.saveOrUpdate(lClassEntity);
		}
	}

	protected String boxResponseString(String color, ClassEntity classEntity,
			String info) {
		String tdvalue = classEntity.getBookingMessage();
		String title = classEntity.getToolTip();
		if (tdvalue.length() > 11) {
			tdvalue = tdvalue.substring(0, 11);
		}
		String rep = "<type>ok</type>" + "<value>" + tdvalue + "</value>"
				+ "<color>" + color + "</color>" + "<title>" + title
				+ "</title>" + "<info>" + info + "</info>";
		return rep;
	}

	public String isCanDoBooking(EClassEntityType bookType, Long entityid,
			Long leadsid, int year, int week, String confirm, String order,
			String comments) {
		if (bookType.equals(EClassEntityType.CANCEL)) {// 取消订课
			return isCanCancel(entityid, leadsid, year, week, confirm);
		} else {// 订课
			ClassEntity classEntity = classArrangeDao.findById(entityid);
			if (classEntity == null) {
				return "ERROR:unknow Class Entity";
			}
			// 如果已定课 直接退出
			if (leadsClassEntityDao.leadsHasThisClassEntity(entityid, leadsid)) {
				return "ERROR:leads has already booking this class";
			}
			if (classEntity.getClassDate().before(
					CalendarUtil.getBeginOfDay(new Date()))) {
				return "ERROR:class before today";
			}
			if (bookType.equals(EClassEntityType.NORMAL)) {
				// 正常订课
				if (classEntity.getType().equals(EClassEntityType.NORMAL)) {
					return isCanDoBookingNormal(classEntity, leadsid, year,
							week, confirm, order, comments);
				} else if (classEntity.getType().equals(EClassEntityType.PSA)) {
					return isCanDoBookingPSA(classEntity, leadsid, year, week,
							confirm, order, comments);
				} else if (classEntity.getType().equals(EClassEntityType.VIP)) {
					return isCanDoBookingVIP(classEntity, leadsid, year, week,
							confirm);
				} else if (classEntity.getType().equals(
						EClassEntityType.FREEF2F)) {
					return isCanDoBookingFreeF2F(classEntity, leadsid, year,
							week, confirm);
				}
			} else if (bookType.equals(EClassEntityType.PSA)) {// 订PSA课程
				return isCanDoBookingPSA(classEntity, leadsid, year, week,
						confirm, order, comments);
			} else if (bookType.equals(EClassEntityType.VIP)) {// 订VIP课程
				return isCanDoBookingVIP(classEntity, leadsid, year, week,
						confirm);
			} else if (bookType.equals(EClassEntityType.FREEF2F)) {// 订VIP课程
				return isCanDoBookingFreeF2F(classEntity, leadsid, year, week,
						confirm);
			}
		}
		return "ERROR:unknow Booking Type";
	}

	/**
	 * 是否可以进行booking
	 * 
	 * @param entityId
	 *            class 的 Id
	 * @param leadsId
	 *            leads 的 Id
	 * @return null, 可以直接订课 WARNING: 需要确认. ERROR:不允许进行订课.
	 */
	public String isCanDoBookingNormal(ClassEntity classEntity, Long leadsId,
			int year, int week, String confirm, String order, String comments) {
		Leads leads = leadsDao.findById(leadsId);
		EClassType classType = classEntity.getClassType().getType();
		// 判断要订的课是否在有效时间里面
		if (classType.equals(EClassType.WK) || classType.equals(EClassType.LC)
				|| classType.equals(EClassType.F2F)) {
			if (!leads.isStudent()) {
				return "ERROR:leads has no Contract";
			}
			if (!leads.isBookingValid(classEntity.getClassDate())) {
				return "ERROR:leads has defer or out contract date";
			}
		}
		// OC判断要订的课是否有合同
		if (classType.equals(EClassType.OC)) {
			if (!leads.isStudent()) {
				return "ERROR:leads has no Contract";
			};
		}
		// 如果F2F 的课程,级别不符合,直接退出.
		if (classEntity.isF2F()) {
			if (!leads.getFinishedOriginalInterview()) {
				return "ERROR:leads has not finsih the OriginalInterview";
			}
			if (leads.getCurrentlevel() == null) {
				return "ERROR:leads has not currentlevel";
			}

			if (classEntity.getTeacher().isForeign()) {
				if (leads.getCurrentlevel().getCategory().equals(
						EClassLevel.L0_2)) {
					return "ERROR:Foreign Teacher but student level 0_2";
				}
			} else {
				if (!leads.getCurrentlevel().getCategory().equals(
						EClassLevel.L0_2)) {
					return "ERROR:Chinese Teacher but student level 3+";
				}
			}

			if (classEntity.getClassLevel() != null
					&& !classEntity.getClassLevel().getCategory().equals(
							leads.getCurrentlevel().getCategory())) {
				return "ERROR:leads has not match booking this F2F class";
			}
		}
		// 判断要订的Interview课是否已经有order了
		if (classType.equals(EClassType.INTERVIEW)) {
			if (order == null || order.trim().length() == 0) {
				return "ERROR:please select class order 1 OR 2";
			}
			// 该课的已定订课情况
			List<LeadsClassEntity> leadsClassEntitys = leadsClassEntityDao
					.getLeadsClassEntityListWithClassEntity(classEntity);
			for (LeadsClassEntity lEntity : leadsClassEntitys) {
				if (lEntity.getClassStatus().equals(ELeadsClassStatus.BOOKING)) {
					if (lEntity.getClassOrder().equals(
							Integer.valueOf(order.trim()))) {
						return "ERROR:please input another class order";
					}
				}
			}
		}

		// 如果无订课权限,直接退出
		// 该学员已本周已订的课程,判断订课总量
		List<LeadsClassEntity> leadsClassList = leadsClassEntityDao
				.getLeadsClassEntityListOrderByBookingTime(year, week, leads);
		int finishClassCount = 0; // 完成的或定的课
		int haveClassCount = 0; // 包括Waiting的课
		for (LeadsClassEntity yClass : leadsClassList) {
			//PSA 不记入F2F cyg100408
			if (!yClass.getClassEntity().getType().equals(EClassEntityType.PSA)) {
				if (yClass.isFinish()) {
					EClassType ct = yClass.getClassEntity().getClassType()
							.getType();
					if (ct.equals(classType)) {
						finishClassCount++;
					}
				}
				if (yClass.isHaving()) {
					EClassType ct = yClass.getClassEntity().getClassType()
							.getType();
					if (ct.equals(classType)) {
						haveClassCount++;
					}
				}
			}
			if ((yClass.getClassStatus().equals(ELeadsClassStatus.BOOKING) || yClass
					.getClassStatus().equals(ELeadsClassStatus.WAITING))
					&& yClass.getClassEntity().getClassDate().equals(
							classEntity.getClassDate())
					&& yClass.getClassEntity().getClassTime().equals(
							classEntity.getClassTime())) {
				if (!yClass.getClassEntity().equals(classEntity)) {// 不是同一节课
					return "ERROR:have the same time class!";
				}
			}
		}
		List<ClassUnit> leadsUnit = leads.getClassUnits();
		boolean canbook = false;
		boolean needAlertCount = false; // 提醒总量超了
		int limit = 0;
		for (ClassUnit unit : leadsUnit) {
			EClassType ct = unit.getClassType().getType();
			if (ct.equals(classType)) {
				//PSA 不记入F2F cyg100408
				if (unit.getClassType().getName().trim().equalsIgnoreCase("PSA")){
					continue;
				}
				limit = unit.getUpdateLimitTimes();
				if (limit <= finishClassCount) {// 总量超了
					String ww = classType.toString() + " limit " + limit
							+ " and already " + finishClassCount;
					return "ERROR:" + ww + "!";
				} else if (limit <= haveClassCount) {
					needAlertCount = true;
					canbook = true;
					break;
				} else {
					canbook = true;
					break;
				}
			}
		}
		if (!canbook) {
			if (classType.equals(EClassType.WK)
					|| classType.equals(EClassType.LC)
					|| classType.equals(EClassType.F2F)) {
				String ww = "student have not " + classType.toString()
						+ " limit ";
				return "ERROR:" + ww + "!";
			}
		}
		// 确认是否需要判断网络课程的情况。
		int confirmM = Integer.valueOf(confirm);
		if (confirmM < 1) {
			if (classType.equals(EClassType.F2F)) {
				if (leads.isNeedJudgeNetLevel()) {
					String com = " Now Level" + leads.getNetLevel() + " Unit"
							+ leads.getNetLevelUnit();
					return "WARNING:Please Check the Students's net class"
							+ com + " !1";
				}
			}
		}
		if (confirmM < 2) {
			// F2F 课不惩罚
			if (classType.equals(EClassType.WK)
					|| classType.equals(EClassType.LC)) {
				if (leads.isNeedPunish(classEntity.getClassDate())) {
					return "WARNING:The leads need punish, confirm booking !2 ";
				}
			}
		}
		if (confirmM < 3) {
			ClassFocus classFocus = classEntity.getClassFocus();
			for (LeadsClassEntity yClass : leadsClassList) {
				if (yClass.isFinish()) {
					ClassFocus fFocus = yClass.getClassEntity().getClassFocus();
					if (fFocus.getId().equals(classFocus.getId())) {
						return "WARNING:The leads have same focus, confirm booking !3 ";
					}
				}
			}
		}
		if (confirmM < 4) {
			if (needAlertCount) {
				int waitCount = haveClassCount - finishClassCount;
				String info = "WARNING:" + classType.toString() + " limit "
						+ limit + " Finish " + finishClassCount + " Wait "
						+ waitCount + " !4";
				return info;
			}
		}
		return null;
	}

	/*
	 * 订PSA的课程
	 * 
	 * @see com.ef.service.ClassBookingService#isCanDoBookingPSA(java.lang.Long,
	 * java.lang.Long, int, int, java.lang.String)
	 */
	public String isCanDoBookingPSA(ClassEntity classEntity, Long leadsId,
			int year, int week, String confirm, String order, String comments) {
		// 如果不是 F2F 的课程
		if (!classEntity.isF2F()) {
			return "ERROR:this class in not F2F";
		}
		if (classEntity.getAllStudent() != 0
				&& !classEntity.getType().equals(EClassEntityType.PSA)) {
			return "ERROR:class have booking";
		}
		if (order == null || order.trim().length() == 0) {
			return "ERROR:please select class order 1 OR 2";
		}
		;
		Leads leads = leadsDao.findById(leadsId);
		// 该学员已本周已订的课程,判断是否有同一时间段的课
		List<LeadsClassEntity> leadsClassList = leadsClassEntityDao
				.getLeadsClassEntityListOrderByBookingTime(year, week, leads);
		for (LeadsClassEntity yClass : leadsClassList) {
			if ((yClass.getClassStatus().equals(ELeadsClassStatus.BOOKING) || yClass
					.getClassStatus().equals(ELeadsClassStatus.WAITING))
					&& yClass.getClassEntity().getClassDate().equals(
							classEntity.getClassDate())
					&& yClass.getClassEntity().getClassTime().equals(
							classEntity.getClassTime())) {
				if (!yClass.getClassEntity().equals(classEntity)) {// 不是同一节课
					return "ERROR:have the same time class!";
				}
			}
		}
		// 该课的已定订课情况
		List<LeadsClassEntity> leadsClassEntitys = leadsClassEntityDao
				.getLeadsClassEntityListWithClassEntity(classEntity);
		for (LeadsClassEntity lEntity : leadsClassEntitys) {
			if (lEntity.getClassStatus().equals(ELeadsClassStatus.BOOKING)) {
				if (lEntity.getClassOrder().equals(
						Integer.valueOf(order.trim()))) {
					return "ERROR:please another class order";
				}
			}
		}
		int confirmM = Integer.valueOf(confirm);
		if (confirmM < 1) {
			if (classEntity.getBookingCount() > 1) {
				return "WARNING:this PSA has " + classEntity.getBookingCount()
						+ " people ,Confirm booking it !1";
			}
		}
		return null;
	}

	public String isCanDoBookingVIP(ClassEntity classEntity, Long leadsId,
			int year, int week, String confirm) {
		// 如果F2F 的课程,级别不符合,直接退出.
		if (!classEntity.isF2F()) {
			return "ERROR:this class in not F2F";
		}
		if (classEntity.getAllStudent() != 0
				&& !classEntity.getType().equals(EClassEntityType.VIP)) {
			return "ERROR:class have booking";
		}
		Leads leads = leadsDao.findById(leadsId);
		// 该学员已本周已订的课程,判断是否有同一时间段的课
		List<LeadsClassEntity> leadsClassList = leadsClassEntityDao
				.getLeadsClassEntityListOrderByBookingTime(year, week, leads);
		for (LeadsClassEntity yClass : leadsClassList) {
			if ((yClass.getClassStatus().equals(ELeadsClassStatus.BOOKING) || yClass
					.getClassStatus().equals(ELeadsClassStatus.WAITING))
					&& yClass.getClassEntity().getClassDate().equals(
							classEntity.getClassDate())
					&& yClass.getClassEntity().getClassTime().equals(
							classEntity.getClassTime())) {
				if (!yClass.getClassEntity().equals(classEntity)) {// 不是同一节课
					return "ERROR:have the same time class!";
				}
			}
		}
		int confirmM = Integer.valueOf(confirm);
		if (confirmM < 1) {
			if (classEntity.getBookingCount() > 0) {
				return "WARNING:this VIP has " + classEntity.getBookingCount()
						+ " people ,Confirm booking it !1";
			}
		}
		return null;
	}

	public String isCanDoBookingFreeF2F(ClassEntity classEntity, Long leadsId,
			int year, int week, String confirm) {
		// 如果F2F 的课程,级别不符合,直接退出.
		if (!classEntity.isF2F()) {
			return "ERROR:this class in not F2F";
		}
		if (classEntity.getAllStudent() != 0
				&& !classEntity.getType().equals(EClassEntityType.FREEF2F)) {
			return "ERROR:class have booking";
		}

		Leads leads = leadsDao.findById(leadsId);
		if (leads.getCurrentlevel() == null) {
			return "ERROR:leads has not currentlevel";
		}
		// 级别>2的不能定FreeF2F 课
		if (!leads.getCurrentlevel().getCategory().equals(EClassLevel.L0_2)) {
			return "ERROR:student level 3+ ";
		}
		if (classEntity.getTeacher().isForeign()) {
			return "ERROR:Foreign can't do Free F2F";
		}

		// 该学员已本周已订的课程,判断是否有同一时间段的课
		List<LeadsClassEntity> leadsClassList = leadsClassEntityDao
				.getLeadsClassEntityListOrderByBookingTime(year, week, leads);
		for (LeadsClassEntity yClass : leadsClassList) {
			if ((yClass.getClassStatus().equals(ELeadsClassStatus.BOOKING) || yClass
					.getClassStatus().equals(ELeadsClassStatus.WAITING))
					&& yClass.getClassEntity().getClassDate().equals(
							classEntity.getClassDate())
					&& yClass.getClassEntity().getClassTime().equals(
							classEntity.getClassTime())) {
				if (!yClass.getClassEntity().equals(classEntity)) {// 不是同一节课
					return "ERROR:have the same time class!";
				}
			}
		}
		int confirmM = Integer.valueOf(confirm);
		if (confirmM < 1) {
			// FreeF2F 没有
			if (classEntity.isFreeF2F()) {
				if (leads.getFreeF2FCount() < 1) {
					return "WARNING:The leads have not free F2F , confirm booking !1 ";
				}
			}
		}
		if (confirmM < 2) {
			if (leads.isNeedJudgeNetLevel()) {
				String com = " Now Level" + leads.getNetLevel() + " Unit"
						+ leads.getNetLevelUnit();
				return "WARNING:Please Check the Students's net class." + com
						+ " !2";
			}
		}
		return null;
	}

	// 修改
	public String isCanCancel(Long entityId, Long leadsId, int year, int week,
			String confirm) {
		// 如果未定课 直接退出
		if (!leadsClassEntityDao.leadsHasThisClassEntity(entityId, leadsId)) {
			return "ERROR:leads  did not booking this class";
		}
		LeadsClassEntity lclass = leadsClassEntityDao
				.getLeadsClassEntityWithClassEntity(entityId, leadsId);
		if (lclass.getClassStatus().equals(ELeadsClassStatus.BOOKING)) {
			// BOOKING 时判断Cancel的次数
			Leads leads = leadsDao.findById(leadsId);
			int confirmM = Integer.valueOf(confirm);
			if (confirmM < 1) {
				if (leads.getCancelTimesInWeek() > 5) {
					return "WARNING:Leads cancel class "
							+ leads.getCancelTimesInWeek()
							+ " times in week,Confirm Cancel !1";
				}
			}
			return null;
		} else if (lclass.getClassStatus().equals(ELeadsClassStatus.WAITING)) {
			// WAITING时直接取消
			return null;
		} else {
			return "ERROR:leads  status:" + lclass.getClassStatus();
		}
	}

	public String isCanChangeStatusToBooking(Long leadsClassEntityId,
			String confirm) {
		LeadsClassEntity leadsClassEntity = leadsClassEntityDao
				.findById(leadsClassEntityId);
		Date date = leadsClassEntity.getClassEntity().getClassDate();
		int year = CalendarUtil.getYearWithMondayIsFirstDay(date);
		int week = CalendarUtil.getWeekOfYearWithMondayIsFirstDay(date);
		ClassEntity classEntity = leadsClassEntity.getClassEntity();
		Leads leads = leadsClassEntity.getLeads();
		if (classEntity.getClassDate().before(
				CalendarUtil.getBeginOfDay(new Date()))) {
			return "ERROR:class before today";
		}
		Integer orderI = leadsClassEntity.getClassOrder();
		String order = "";
		if (orderI != null) {
			order = orderI.toString();
		}
		String comments = "ChangeStatusToBooking";
		if (classEntity.getType().equals(EClassEntityType.NORMAL)) {
			return isCanDoBookingNormal(classEntity, leads.getId(), year, week,
					confirm, order, comments);
		} else if (classEntity.getType().equals(EClassEntityType.PSA)) {
			return isCanDoBookingPSA(classEntity, leads.getId(), year, week,
					confirm, order, comments);
		} else if (classEntity.getType().equals(EClassEntityType.VIP)) {
			return isCanDoBookingVIP(classEntity, leads.getId(), year, week,
					confirm);
		} else if (classEntity.getType().equals(EClassEntityType.FREEF2F)) {
			return isCanDoBookingFreeF2F(classEntity, leads.getId(), year,
					week, confirm);
		}
		return "ERROR:unknow Booking Type";
	}

	public List<CardInfo> bookingStudentsInfo(Date today,
			String classEntityType, String classType) {
		return classBookingDao.bookingStudentsInfo(today, classEntityType,
				classType);
	}

	public ClassBookingDao getClassBookingDao() {
		return classBookingDao;
	}

	public void setClassBookingDao(ClassBookingDao classBookingDao) {
		this.classBookingDao = classBookingDao;
	}

	public ClassArrangeDao getClassArrangeDao() {
		return classArrangeDao;
	}

	public void setClassArrangeDao(ClassArrangeDao classArrangeDao) {
		this.classArrangeDao = classArrangeDao;
	}

	public LeadsClassEntityDao getLeadsClassEntityDao() {
		return leadsClassEntityDao;
	}

	public void setLeadsClassEntityDao(LeadsClassEntityDao leadsClassEntityDao) {
		this.leadsClassEntityDao = leadsClassEntityDao;
	}

	public TodoEventDao getTodoEventDao() {
		return todoEventDao;
	}

	public void setTodoEventDao(TodoEventDao todoEventDao) {
		this.todoEventDao = todoEventDao;
	}

	public LeadsDao getLeadsDao() {
		return leadsDao;
	}

	public void setLeadsDao(LeadsDao leadsDao) {
		this.leadsDao = leadsDao;
	}
}
